package com.example.lotterysystem.common.utils;

import cn.hutool.jwt.JWTUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;

import io.jsonwebtoken.JwtParserBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 令牌实现
 */
@Slf4j
public class JwtUtil{
    private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);

    //密钥
    public static String secretStr =
            "5QGoH4qLyxEw7vAccxo2KHg26iJztJvJlaT9MKTatqI=";
    /**
     * 生成安全密钥：将一个Base64编码的密钥解码并创建一个HMAC SHA密钥。
     */
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(
            Decoders.BASE64.decode(secretStr));
    //过期时间(单位: 毫秒)
    public static long JWT_EXPIRATION = 24*60*60*1000;//⼀天


    /**
     * 生成JWT令牌
     *
     * @param claim 包含要添加到JWT中的自定义声明或数据
     * @return 返回生成的JWT令牌字符串
     */

    public static String genJwtToken(Map<String,Object> claim){
        // 开始构建JWT令牌
        String token = Jwts.builder()
                .setClaims(claim)  // 设置JWT中的自定义声明或数据
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis()+JWT_EXPIRATION))  // 设置令牌的过期时间 当前毫秒加上设置的时间
                .signWith(SECRET_KEY)  // 使用密钥对令牌进行签名
                .compact();  // 将令牌压缩为字符串形式
        logger.error("生成JWT令牌成功：{}",token);
        return  token;
    }

    /**
     * 校验token
     * claims为 null 表示校验失败
     */
    public static Claims parseToken(String token) {
        // 判断token是否为空
        if (!StringUtils.hasLength(token)) return null;
//        创建解析器, 设置签名密钥
        JwtParserBuilder jwtParserBuilder = Jwts.parserBuilder().setSigningKey(SECRET_KEY);
        Claims claims = null;
        try {
            //解析token
            claims = jwtParserBuilder.build().parseClaimsJws(token).getBody();
        } catch (Exception e) {
            logger.error("校验token失败：{}", e);
            return null;
        }
        return claims;
    }
    /**
     * 从token中获取用户ID
     * @param token
     * @return
     */
    public static Integer getIdByToken(String token){
        Claims claims = parseToken(token);
        if(claims !=null){
           Map<String,Object> userInfo = new HashMap<>(claims);
           return (Integer) userInfo.get("userId");
        }
        return null;
    }
}
